#ifndef CIPODIAP2_H_
#define CIPODIAP2_H_

#include <list>
#include <string>
#include "Iap2Def.h"
#include "CIpodProtocol.h"
#include "CIap2Sqlite.h"
#include "DataReceiver.h"

#ifdef __cplusplus
extern "C"{
#endif

class CIpodIap2 : public CIpodProtocol {
public:
    CIpodIap2();
    ~CIpodIap2();

private:
    int init(int connMode);
    int deinit();
    int packetProc(const uint8 *data, uint16 len, bool native);

    /************************************************************************************
     * Variables
     ************************************************************************************/
    uint8                           m_SendHttpInfo;
    uint8                           m_SendVehiclePacketAckNumber;
    uint8                           m_SyncNumber;
    uint8                           m_AckNumber;
    uint8                           m_connMode;
    uint8                           m_AccessoryAckNumber;
    int                             m_AuthenticationState;
    int                             m_IdentificationState;
    std::list<uint16>               m_MessagesSent;
    std::list<uint16>               m_MessagesReceived;
    bool                            m_ReqSerialNumber;
    bool                            m_TouchEnabled;
    bool                            m_PrductPlanUIDEnabled;
    bool                            m_A2dpConnected;
    std::string      				m_DeviceInformation;
    DeviceTransportNotification	    m_DeviceTransportId;
    int                             m_WirelessAvailable;
    RouteGuidanceUpdate             m_route_guidance_update;
    RouteGuidanceManeuverUpdate     m_route_guidance_maneuver_update;
    CarPlayAvailInfo                m_CarPlayAvail;
    std::string                     m_DeviceLanguage;
    uint16                          m_MediaHID;
    IAP2EAPStatus                   m_EAPStatus;
    IAP2NowPlaying                  m_NowPlaying;
    IAP2CallStatusInfo              m_CallStatus;
    IAP2LocationType                m_LocationType;
    std::list<IAP2FileTransfer *>   m_FileTransfers;
    IAP2MediaLibrary                m_LocalDeviceLibrary;
    CIap2Sqlite                     m_LocalDeviceSqlite;
    IAP2MediaLibrary                m_MusicRadioLibrary;
    CIap2Sqlite                     m_MusicRadioSqlite;
    std::list<IAP2MediaList>        m_MediaLists;
    IAP2FilePlayingList             m_FilePlayingLists;
    DataReceiver *                  m_DataReceiverPtr;

    /************************************************************************************
     * Link Control
     ************************************************************************************/
    uint16 createLinkPacket(IAP2_CONTROL_BYTE control, uint8 syncNumber, uint8 ackNumber, uint8 sessionID, const uint8 *payload, uint16 payloadLen, IAP2_LINK_PACKET_OUT *desbuf);
    uint16 createPayloadPacket(uint8 messageMainID, uint8 messageSubID, const uint8 *payload, uint16 payloadLen, uint8 *desbuf);
    uint16 createParamPacket(uint16 paramID, const uint8 *param, uint16 paramLen, uint8 *desbuf);
    uint16 sharkParseIdentificationParamPacket(const uint8 *param, uint16 paramLen);
    uint16 sharkParseAuthenticationCertificateParamPacket(const uint8 *param, uint16 paramLen);
    int increaseSendVehiclePacketAckNumber();
    void increaseSyncNumber();
    int write(const uint8 *data, uint16 len);
    void onCumulativeAcknowledgementTimeout();
    int sendAckPacket();
    int sendResetPacket();
    int sendSyncAckPacket();
    int syncLink(int connMode);
    int syncAckLinkParameters(int connMode);
    int sharkRequestIdentification();
    int sharkAcceptedIdentification();
    int syncLinkResult(const uint8 *payload,const int payloadLength);
    int initMessages(int connMode);
    int sharkLastStep( );

    /************************************************************************************
     * Control Session
     ************************************************************************************/
    int sharkParseIdentificationInformation(const uint8 *data, uint16 len);
    int sharkParseAuthenticationCertificate(const uint8 *data, uint16 len);
    int sharkParseAccessoryAuthenticationSerialNumber(const uint8 *data, uint16 len);
    int sharkParseAccessoryAuthenticationResponse(const uint8 *data, uint16 len);
    int sharkParseStartPowerUpdates(const uint8 *data, uint16 len);
    int sharkLookupMsgSentReceiveCompleted();
    int sharkLookupCustinCompleted();
    int sharkLookupMGCompleted();
    int sharkLookupNissianJukeCompleted();
    int sharkLookupBMWID7Completed();
    int sharkLookupBMWID85Completed();

    /************************************************************************************
     * File Transfer Session
     ************************************************************************************/
    int parseFileTransfer(const uint8 *data, uint16 len);
    int saveFileTransfer(IAP2FileTransfer *transfer);

    /************************************************************************************
     * EA Session
     ************************************************************************************/
    int parseEAData(const uint8 *data, uint16 len);

    /************************************************************************************
     * Interface
     ************************************************************************************/
    int notifyBtStatus(bool connected);
    int notifyUSBAudioStatus(bool enabled);
    int sendMediaCommand(int command);
    int sendMediaCommandDown(int command);
    int sendMediaCommandUp(int command);
    int sendMediaCommandLibraryInfo(void * mediaInfo);
    int sendStartLocationInformation(int start);
    int sendStartDeviceTimeUpdate( );
    int sendCallStateUpdateInfo(void * callStateInfo);
    int setPlayingTrackPosition(uint32 position);
    int getShuffleMode(int *mode);
    int getRepeatMode(int *mode);
    int getPlayingTrackDuration(int * duration);
    int getPlayingTrackTitle(std::string &title);
    int getPlayingTrackAlbum(std::string &album);
    int getPlayingTrackArtist(std::string &artist);
    int getPlayingTrackAlbumArtwork();
    int getPlayStatus(IPODPlayStatus *status);
    int getPlayingTrackInfo(int32 *index, uint32 *count);
    int getPlayingChapterInfo(int32 *index, uint32 *count);
    int isListLevelSupported(bool *supported);
    int resetMusicList(uint32 *num);
    int selectMusicList(int32 index, int32 level, uint32 *num);
    int selectMusicPlayingList(int32 index);
    int getMusicList(uint32 startIndex, uint32 readCount, IPODMusicList *musicList);
    int getMusicList_c(uint32 startIndex, uint32 readCount, C_IPODMusicList *musicList);
    int getMusicPlayingList(uint32 startIndex, uint32 readCount, C_IPODMusicList *musicList);
    int launchApp(const char *appBundleID);
    int sendEAData(const uint8 *data, uint16 len);
    int setLocationInformation(const char *sentence);
    int carPlayStartSession(int type);
    void getIPv6( char * address, const char * inInterfaceName );
    int iap2OOBBTPairingCompletionInformation(int resultCode );
    int iap2BluetoothPairingAccessoryInformation(const char * inPairingDataP192,const char * inPairingDataP256);
    int iap2BluetoothPairingStatus( int success, const char * cancelReason);

    /************************************************************************************
     * Protocol
     ************************************************************************************/
    /* Authentication */
    int requestAuthenticationCertificate(const uint8 *data);
    int sharkRequestAuthenticationCertificate();
    int sharkRequestAuthenticationCertificateSerialNumber();
    int sharkRequestAuthenticationChallengeResponse();
    int sharkRequestAuthenticationSucceeded();
    int sharkRequestStartLocationInformation();
    int sharkRequestGPRMCDDataStatusValuesNotification();
    int sharkRequestDeviceInformationUpdate();
    int sharkRequestWirelessCarPlayUpdate();
    int sharkRequestDeviceUUIDUpdate();
    int sharkRequestListUpdate();
    int sharkRequestAppDiscoveryUpdate();
    int sharkRequestStartVehicleStatusUpdates();
    int sharkRequestAccessoryWiFiConfigurationInformation();
    int sharkRequestBluetoothConnectionUpdate(const uint8 *data, uint16 len);
    int sharkRequestBluetoothConnectionUpdateNoParam();
    int sharkRequestStartCallStateInfoUpdates(void * callStateInfo);
    int sharkRequestStartCallStateUpdates();
    int sharkRequestStartCommunicationsUpdates(const uint8 *data, uint16 len);
    int sharkRequestStartCommunicationsUpdatesBmwID7();
    int sharkRequestStartRouteGuidanceUpdates();
    int sharkRequestDeviceLanguageUpdate();
    int sharkRequestDeviceTimeUpdate();
    int sharkRequestUSBDeviceModeAudioInformation();
    int sharkRequestMediaLibraryInformation();
    int sharkRequestMediaLibraryUpdate();
    int sharkRequestNowPlayingUpdate(std::string title,std::string album, std::string artist,uint8 playStatus,long duration,long elapsedTime);
    int sharkRequestNowPlayingUpdateInit();
    int sharkRequestCarPlayAvailability();
    int sharkRequestDeviceTransportIdentifierNotification();
    int sharkRequestStartExternalAccessoryProtocolSession();
    int authenticationCertificate(const uint8 *certificate, uint16 len);
    int requestAuthenticationChallengeResponse(const uint8 *data);
    int authenticationResponse(const uint8 *response, uint16 len);
    int authenticationFailed();
    int authenticationSucceeded();
    int accessoryAuthenticationSerialNumber();

    /* Identification */
    int startIdentification();
    int identificationInformation();
    int identificationAccepted();
    int identificationRejected(const uint8 *data);
    int cancelIdentification();
    int identificationInformationUpdate();

    /* App Launch */
    int requestAppLaunch(std::string appBundleID);
    int requestAppLaunch(std::string appBundleID, int method);

    /* Assistive Touch */
    int startAssistiveTouch();
    int stopAssistiveTouch();
    int startAssistiveTouchInformation();
    int assistiveTouchInformation(const uint8 *data);
    int stopAssistiveTouchInformation();

    /* Bluetooth Connection */
    int bluetoothComponentInformation(bool connected);
    int startBluetoothConnectionUpdates();
    int bluetoothConnectionUpdate(const uint8 *data);
    int stopBluetoothConnectionUpdates();
    void parseConnectedBluetoothProfiles(const uint8 *data, uint16 len);

    /* Communications */
    int startCallStateUpdates();
    int callStateUpdate(const uint8 *data);
    int stopCallStateUpdates();
    int startCommunicationsUpdates();
    int communicationsUpdate(const uint8 *data);
    int stopCommunicationsUpdates();
    int initiateCall();
    int acceptCall();
    int endCall();
    int swapCall();
    int mergeCall();
    int holdStatusUpdate();
    int muteStatusUpdate();
    int sendDTMF();
    int startListUpdates();
    int listUpdate(const uint8 *data);
    int stopListUpdates();

    /* Device Authentications */
    int requestDeviceAuthenticationCertificate();
    int deviceAuthenticationCertificate(const uint8 *data);
    int RequestDeviceAuthenticationChallengeResponse(const uint8 *challenge, uint16 len);
    int deviceAuthenticationResponse(const uint8 *data);
    int deviceAuthenticationFailed();
    int deviceAuthenticationSucceeded();
	int getDeviceInformation();

    /* Device Notifications */
    int deviceInformationUpdate(const uint8 *data);
    int deviceLanguageUpdate(const uint8 *data);
    int deviceTimeUpdate(const uint8 *data);
    int deviceUUIDUpdate(const uint8 *data);
    int wirelessCarPlayUpdate(const uint8 *data);
    int deviceTransportIdentifierNotification(const uint8 *data);

    /* External Accessory Protocol */
    int startExternalAccessoryProtocol(const uint8 *data);
    int stopExternalAccessoryProtocol(const uint8 *data);
    int statusExternalAccessoryProtocol(uint16 sessionID, int status);

    /* Human Interface Device */
    int startHID(uint16 id, uint16 vid, uint16 pid, const uint8 *descriptor, uint16 descriptorSize);
    int deviceHIDReport(const uint8 *data);
    int accessoryHIDReport(uint16 id, const uint8 *report, uint16 reportSize);
    int stopHID(uint16 id);
    int startNativeHID();

    /* Location */
    int startLocationInformation(const uint8 *data);
    int GPRMCDDataStatusValuesNotification(const uint8 *data);
    int locationInformation(std::string nmeaSentences);
    int stopLocationInformation();

    /* Media Library Access */
    int initMedia();
    int deinitMedia();
    int startMediaLibraryInformation();
    int mediaLibraryInformation(const uint8 *data);
    int stopMediaLibraryInformation();
    int startMediaLibraryUpdates(std::string libraryID);
    int mediaLibraryUpdate(const uint8 *data);
    int stopMediaLibraryUpdates(std::string libraryID);
    int playMediaLibraryCurrentSelection(std::string libraryID);
    int playMediaLibraryItems(std::string libraryID, const uint64 *itemids, uint16 itemSize, uint32 startIndex);
    int playMediaLibraryCollection(std::string libraryID, uint64 collectionID, int type, uint32 startIndex);
    int playMediaLibrarySpecial(std::string libraryID, bool allSongs);
    int parseMediaLibraryInformation(const uint8 *data, uint16 len);
    int parseMediaLibraryItem(const uint8 *data, uint16 len, IAP2MediaItem *item);
    int parseMediaLibraryPlaylist(const uint8 *data, uint16 len, IAP2MediaPlaylist *playlist);

    /* Now Playing */
    int startNowPlayingUpdates();
    int nowPlayingUpdate(const uint8 *data);
    int stopNowPlayingUpdates();
    int setElapsedTime(uint32 time);
    int setPlaybackQueueIndex(uint32 index);
    int parseNowPlayingMediaItem(const uint8 *data, uint16 len);
    int parseNowPlayingPlayback(const uint8 *data, uint16 len);


    /* Out-of-Band Bluetooth Pairing R2*/
    int startOOBBTPairing(const uint8 *data);
    int oOBBTPairingAccessoryInformation();
    int oOBBTPairingLinkKeyInformation(const uint8 *data);
    int oOBBTPairingCompletionInformation(int resultCode);
    int stopOOBBTPairing(const uint8 *data);

    /* Out-of-Band Bluetooth Pairing R37*/
    int startBluetoothPairing(const uint8 *data);
    int bluetoothPairingAccessoryInformation(const char * inPairingDataP192,const char * inPairingDataP256);
    int bluetoothPairingStatus( int success, const char * cancelReason);
    int stopBluetoothPairing(const uint8 *data);

    /* Power */
    int startPowerUpdates();
    int sharkPowerUpdates();
    int sharkPowerUpdates0();
    int sharkPowerUpdates1();
    int sharkPowerUpdates2();
    int sharkPowerUpdates4();
    int sharkPowerUpdates5();
    int sharkPowerUpdates6();
    int powerUpdate(const uint8 *data);
    int stopPowerUpdates();
    int powerSourceUpdate(uint16 value);
    int sharkParsePowerSourceUpdate(const uint8 *data, uint16 len);
    int sharkParseStartHIDInformation(uint8 *data, uint16 len);
    int sharkParseAccessoryHIDReport(uint8 *data, uint16 len);
    int sharkParseAccessoryWiFiConfigurationInformation(uint8 *data, uint16 len);
    int sharkParseCarPlayStartSession(uint8 *data, uint16 len);
    int sharkParseLocationInformation(const uint8 *data, uint16 len);

    /* Route Guidance */
    int startRouteGuidanceUpdate();
    int routeGuidanceUpdate(const uint8 *data);
    int routeGuidanceManeuverInformation(const uint8 *data);
    int stopRouteGuidanceUpdate();

    /* USB Device Mode Audio */
    int startUSBDeviceModeAudio();
    int usbDeviceModeAudioInformatin(const uint8 *data);
    int stopUSBDeviceModeAudio();

    /* Vehicle Status */
    int startVehicleStatusUpdates(const uint8 *data);
    int vehicleStatusUpdate();
    int stopVehicleStatusUpdates();

    /* Voice Over */
    int startVoiceOver();
    int stopVoiceOver();
    int requestVoiceOverMoveCursor();
    int requestVoiceOverActivateCursor();
    int requestVoiceOverScrollPage();
    int requestVoiceOverSpeakText();
    int requestVoiceOverPauseText();
    int requestVoiceOverResumeText();
    int startVoiceOverUpdates();
    int voiceOverUpdate(const uint8 *data);
    int stopVoiceOverUpdates();
    int requestVoiceOverConfiguration();
    int startVoiceOverCursorUpdates();
    int voiceOverCursorUpdate(const uint8 *data);
    int stopVoiceOverCursorUpdates();

    /* WiFi Information Sharing */
    int requestWiFiInformation();
    int wifiInformation(const uint8 *data);
    int requestAccessoryWiFiConfigurationInformation();
    int accessoryWiFiConfigurationInformation();
    int carPlayAvailability(const uint8 *data);
    int parseCarPlayAvailabilityWiredAttributes(const uint8 *data, uint16 len);
    int parseCarPlayAvailabilityWirelessAttributes(const uint8 *data, uint16 len);


    void debugHexBuf(const char *tag, const uint8 *data, uint16 len);
    void debugHexBuf1(const char *tag, const char *data , uint16 len);
};

#ifdef __cplusplus
}
#endif

#endif /* CIPODIAP2_H_ */
